﻿using System;
using System.Collections.Generic;
using System.Text;
using System.Text.RegularExpressions;
using Wangzeran.CodeMaker.Core.Tag;

namespace Wangzeran.CodeMaker.Core.Template
{
    /// <summary>
    /// 模板支持
    /// </summary>
    public abstract class TemplateSupport : ITemplate
    {

        #region 正则表达式

        /// <summary>
        /// 匹配标签完整
        /// </summary>
        protected const string PATTERN_TAG_END = @"</c:.+?>";
        /// <summary>
        /// 匹配标签开始
        /// </summary>
        protected const string PATTERN_TAG_BEGIN = @"<c:.+?[^/]>";
        /// <summary>
        /// 匹配标签开始
        /// </summary>
        protected const string PATTERN_TAG_FULL = @"<c:.*?/>";
        /// <summary>
        /// 匹配标签开始（贪婪）
        /// </summary>
        protected const string PATTERN_TAG_FULL_GREED = "<c:.+?>(\"./>)|<c:.+?\"./>";
        /// <summary>
        /// 匹配标签
        /// </summary>
        //protected const string PATTERN_TAG = @"<c:.+>";
        //protected const string PATTERN_TAG = "<c:.+?>(\"./>)|<c:.+?>";
        protected const string PATTERN_TAG = "<c:.+?\".?/>";
        /// <summary>
        /// 匹配标签名称
        /// </summary>
        protected const string PATTERN_TAGNAME = @"c:[^\W][^<]\S+[^\s]";

        #endregion


        #region ITemplate 成员
        /// <summary>
        /// 模板名称
        /// </summary>
        public abstract string TemplateName
        {
            get;
        }

        /// <summary>
        /// 执行模板
        /// </summary>
        /// <param name="templatePath">模板文件</param>
        /// <returns>模板结果</returns>
        public abstract string ExecuteTempldate(string templatePath, object value, out string fileName);

        /// <summary>
        /// 执行模板
        /// </summary>
        /// <param name="contents">模板内容</param>
        /// <param name="value">模板值</param>
        /// <returns>模板结果</returns>
        public abstract string ExecuteTempldateContents(string contents, object value, out string fileName);

        /// <summary>
        /// 将此实例转换为System.String对象
        /// </summary>
        /// <returns></returns>
        public override string ToString()
        {
            Type t = this.GetType();
            StringBuilder sb = new StringBuilder();
            sb.Append(t.FullName);
            sb.Append(", ");
            sb.Append(t.Assembly.FullName);
            return sb.ToString();
        }

        #endregion


        #region 解析标签 

        /// <summary>
        /// 是否包含标签
        /// </summary>
        /// <param name="line">行文本</param>
        /// <returns></returns>
        protected bool HasBeginTag(string line)
        {
            bool result = Regex.IsMatch(line, PATTERN_TAG_BEGIN, RegexOptions.IgnoreCase);
            return result;
        }

        /// <summary>
        /// 是否包含标签
        /// </summary>
        /// <param name="line">行文本</param>
        /// <returns></returns>
        protected bool HasEndTag(string line)
        {
            bool result = Regex.IsMatch(line, PATTERN_TAG_END, RegexOptions.IgnoreCase);
            return result;
        }

        /// <summary>
        /// 是否包含标签
        /// </summary>
        /// <param name="line">行文本</param>
        /// <returns></returns>
        protected bool HasFullTag(string line)
        {
            bool result = Regex.IsMatch(line, PATTERN_TAG_FULL_GREED, RegexOptions.IgnoreCase);
            return result;
        }

        /// <summary>
        /// 获取包含的标签
        /// </summary>
        /// <param name="line">行文本</param>
        /// <returns></returns>
        protected string[] GetTags(string line)
        {
            string[] tags = null;
            line = line.Trim();
            MatchCollection matchs = Regex.Matches(line, PATTERN_TAG, RegexOptions.IgnoreCase & RegexOptions.Singleline);
            tags = new string[matchs.Count];
            for (int i = 0; i < tags.Length; i++)
            {
                tags[i] = matchs[i].Value;
            }
            return tags;
        }

        /// <summary>
        /// 解析标签
        /// </summary>
        /// <param name="tagStr">标签文本</param>
        /// <returns></returns>
        protected ITag ParseTag(string tagStr)
        {
            ITag tag = null;
            string[] lines =
                tagStr.Split(new string[] { Environment.NewLine }, StringSplitOptions.None);
            if (lines.Length > 0)
            {
                Match match = Regex.Match(lines[0], PATTERN_TAGNAME, RegexOptions.IgnoreCase);
                if (match.Success)
                {
                    tag = TagPlugIns.InstanceTag(match.Value);
                }
            }
            return tag;
        }

        #endregion
    }
}
